// Metgine/Core/Renderer.h
//
// Copyright 2011 Phillip Stephens
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library.  Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.

#ifndef __RENDERER_H__
#define __RENDERER_H__

#include <SFML/Graphics.hpp>

#include <Metgine/Core/Vector2.h>
#include <Metgine/Core/BoundingBox.h>
#include <Metgine/Core/Singleton.h>
#include <Metgine/Core/FontResource.h>
#include <Metgine/Graphics/Renderable.h>
#include <Metgine/Graphics/Shape.h>
#include <Metgine/Graphics/String.h>

using namespace Metgine::Graphics;

namespace Metgine
{
namespace Core
{

class Camera;

class METGINE_API Renderer : public Singleton<Renderer>
{
    friend class Singleton<Renderer>;

public:
    void Initialize(int, int, int, const char*, bool = false);
    void UpdateWindow();

    void DoEvents();
    void Clear(sf::Color = sf::Color::Black);
    void Present();

    void Render(const Graphics::Renderable&);

    sf::RenderWindow& GetWindow();

    void SetIcon(sf::Image&);
    void SetCamera(Camera*);// Not implemented

    // Draws a debug circle
    void DrawDebugCircle(const Vector2f& center, float radius, const sf::Color& color);

    // Draws a debug ray
    void DrawDebugRay(const Vector2f& start, const Vector2f& direction, float length, const sf::Color& color);

    // Draws a debug line
    void DrawDebugLine(const Vector2f& start, const Vector2f& end, const sf::Color& color);

    // Draws a debug arrow
    void DrawDebugArrow(const Vector2f& start, const Vector2f& end, const sf::Color& color);

    // Draws a debug trajectory
    void DrawDebugTrajectory(const Vector2f& start, const Vector2f& direction, float initialSpeed, float absGravity, const sf::Color& color);

    // Draws a debug hint box
    void DrawDebugHint(const Vector2f& position, const std::string& text, const sf::Color& color = sf::Color::White);

    // Draws a debug box
    void DrawDebugBoundingBox(const BoundingBoxf& box, const sf::Color& color);

    // Draws a debug point
    void DrawDebugPoint(const Vector2f& point, const sf::Color& color);

    // Draws all queued debug shapes
    void DebugDraw();

    // Sets the default font
    void SetDefaultFont(FontResource* font);

    // Render text to the screen
    void RenderText(float x, float y, FontResource* fontResource, const std::string& text, float size = 30.0f, const sf::Color& color = sf::Color(255, 255, 255), unsigned int flags = FontFlag::None);

    // Measures a text string
    BoundingBoxf MeasureText(const std::string& text, FontResource* fontResource, float size);

    // Render text to the screen with a shadow effect
    void RenderTextShadowed(float x, float y, FontResource* fontResource, const std::string& text, const float spacing = 2.0f, float size = 30.0f, const sf::Color& color = sf::Color(255, 255, 255), const sf::Color& shadow = sf::Color(0, 0, 0), unsigned int flags = FontFlag::None);

    void SetFullscreen(bool);
    bool IsFullscreen();

    void SetTitle(const std::string& title);

    int GetWidth() const;
    int GetHeight() const;

    Vector2i GetRelativeCoordinate(int, int RenderPosition);

private:
    Renderer();
    virtual ~Renderer();

    sf::RenderWindow          m_window;
    Camera*                   m_camera;
    std::vector<Renderable*>  m_debugLayer;
    FontResource*             m_defaultFont;
    Vector2i                  m_resolution;
    bool                      m_fullscreen;
    std::string               m_windowTitle;
    float                     m_fade;
};

}; // Grapihcs

}; // Metgine
#endif // RENDERER_H
